package com.nineclock.document.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.enums.DocumentPermissionEnum;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.CountUtil;
import com.nineclock.document.dto.DocFileDto;
import com.nineclock.document.dto.DocFolderDto;
import com.nineclock.document.dto.DocumentDto;
import com.nineclock.document.mapper.DocCollaborationsMapper;
import com.nineclock.document.mapper.DocFileHistoryMapper;
import com.nineclock.document.mapper.DocFileMapper;
import com.nineclock.document.mapper.DocFolderMapper;
import com.nineclock.document.pojo.DocCollaborations;
import com.nineclock.document.pojo.DocFile;
import com.nineclock.document.pojo.DocFileHistory;
import com.nineclock.document.pojo.DocFolder;
import com.nineclock.document.service.DocumentService;
import com.nineclock.model.dto.SysCompanyUserDTO;
import com.nineclock.system.feign.SysUserFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DocumentServiceImpl implements DocumentService {

    @Autowired
    DocFileMapper docFileMapper;
    @Autowired
    DocFolderMapper docFolderMapper;
    @Autowired
    DocCollaborationsMapper docCollaborationsMapper;
    @Autowired
    SysUserFeign userFeign;
    @Autowired
    DocFileHistoryMapper docFileHistoryMapper;

    @Override
    public DocumentDto queryFolderAndFile(Long parentFolderId) {
        //查询文件夹列表
        List<DocFolderDto> folderDtoList = this.queryFoldersByParentFolderId(parentFolderId);

        //查询文件列表
        List<DocFileDto> fileDtoList = this.queryFilesByFolderId(parentFolderId);


        DocumentDto documentDto = new DocumentDto(folderDtoList, fileDtoList);

        return documentDto;
    }

    @Override
    public void insertFolder(DocFolderDto docFolderDto) {
        if (docFolderDto==null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //保存文件夹
        DocFolder docFolder = BeanHelper.copyProperties(docFolderDto, DocFolder.class);
        docFolder.setStatus((short) 1);
        docFolder.setCompanyId(CurrentUserHolder.get().getCompanyId());
        docFolder.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFolder.setOrderNum(0);
        docFolderMapper.insert(docFolder);
    }

    @Override
    public void insertFile(DocFileDto docFileDto)  {
        if (docFileDto==null||StringUtils.isEmpty(docFileDto)) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //保存文件夹
        DocFile docFile = BeanHelper.copyProperties(docFileDto, DocFile.class);
        docFile.setStatus((short) 1);
        docFile.setCompanyId(CurrentUserHolder.get().getCompanyId());
        docFile.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFile.setCreateTime(new Date());
        docFile.setPermission(DocumentPermissionEnum.PRIVATE_READ_WRITE.getPermission());
        //docFile.setFileSize(CountUtil.getSize(docFileDto.getContent().getBytes("utf-8").length));
        docFile.setUpdateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFileMapper.insert(docFile);

        //保存文档历史信息
        DocFileHistory docFileHistory = new DocFileHistory();
        docFileHistory.setFileId(docFile.getId());
        docFileHistory.setFileName(docFile.getName());
        docFileHistory.setOperateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFileHistory.setOperateTime(new Date());
        docFileHistory.setIsCreate((short)1);
        docFileHistory.setContent(docFile.getContent());

        docFileHistoryMapper.insert(docFileHistory);
    }

    @Override
    public DocFileDto getFileByFileId(Long fileId) {
        DocFile docFile = docFileMapper.selectById(fileId);
        if(docFile == null){
            throw new NcException(ResponseEnum.FILE_NOT_FOUND);
        }
        return BeanHelper.copyProperties(docFile,DocFileDto.class);
    }
    private Boolean checkAuth(DocFileDto docFileDto) {
        //判断是否有编辑权限
        DocFile docFile = docFileMapper.selectById(docFileDto.getId());
        if (docFile==null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        if (docFile.getPermission()==DocumentPermissionEnum.ALL_READ_WRITE.getPermission()) {
            return true;
        }

        if (docFile.getPermission()==DocumentPermissionEnum.PRIVATE_READ_WRITE.getPermission()) {
            if (docFile.getCreateUserId() == CurrentUserHolder.get().getCompanyUserId()) {
                return true;
            }
        }
        //协作者
        if (docFile.getPermission() == DocumentPermissionEnum.ALL_READ.getPermission()) {
            LambdaQueryWrapper<DocCollaborations> collaborationsLambdaQueryWrapper = new LambdaQueryWrapper<>();
            collaborationsLambdaQueryWrapper.eq(DocCollaborations::getFileId,docFile.getId());

            List<DocCollaborations> docCollaborations = docCollaborationsMapper.selectList(collaborationsLambdaQueryWrapper);
            List<Long> collIds = docCollaborations.stream().map(docCollaborations1 -> {
                return docCollaborations1.getCollaborationId();
            }).collect(Collectors.toList());

            if (collIds !=null&&collIds.contains(CurrentUserHolder.get().getCompanyUserId())) {
                return true;
            }
        }


        return false;
    }


    @Override
    public void updateFile(DocFileDto docFileDto) throws UnsupportedEncodingException  {
        if (docFileDto==null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        Boolean flag = this.checkAuth(docFileDto);
        if (!flag) {
            throw new NcException(ResponseEnum.FILE_WRITE_NOT_PERMIT);
        }

        //更新文件信息
        DocFile docFile = BeanHelper.copyProperties(docFileDto, DocFile.class);
        docFile.setUpdateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFile.setFileSize(CountUtil.getSize(docFile.getContent().getBytes("utf-8").length));
        docFileMapper.updateById(docFile);

        //记录文件编辑历史
        DocFileHistory docFileHistory = new DocFileHistory();
        docFileHistory.setOperateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFileHistory.setIsCreate((short)0);
        docFileHistory.setFileId(docFile.getId());
        docFileHistory.setContent(docFile.getContent());
        docFileHistory.setFileName(docFile.getName());

        docFileHistoryMapper.insert(docFileHistory);

    }
    //-------------------未完成--------------
    @Override
    public DocumentDto pagingFile(Integer page, Integer pageSize, String keyword) {

        return null;
    }
    //--------------------------------------
    /**
     * 查询文件列表
     *
     * @param parentFolderId
     * @return
     */
    private List<DocFileDto> queryFilesByFolderId(Long parentFolderId) {

        //查询当前目录下公共读和公共读写的文件
        LambdaQueryWrapper<DocFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DocFile::getCompanyId, CurrentUserHolder.get().getCompanyId());
        queryWrapper.in(DocFile::getPermission, DocumentPermissionEnum.ALL_READ.getPermission(), DocumentPermissionEnum.ALL_READ_WRITE.getPermission());
        queryWrapper.eq(DocFile::getStatus, 1);
        queryWrapper.eq(DocFile::getFolderId, parentFolderId);
        List<DocFile> docFiles = docFileMapper.selectList(queryWrapper);

        //查询当前目录下私有的文件
        LambdaQueryWrapper<DocFile> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(DocFile::getCompanyId, CurrentUserHolder.get().getCompanyId());
        queryWrapper1.eq(DocFile::getCreateUserId, CurrentUserHolder.get().getCompanyUserId());
        queryWrapper1.in(DocFile::getPermission, DocumentPermissionEnum.PRIVATE_READ_WRITE.getPermission());
        queryWrapper1.eq(DocFile::getStatus, 1);
        queryWrapper1.eq(DocFile::getFolderId, parentFolderId);
        List<DocFile> docFiles1 = docFileMapper.selectList(queryWrapper1);

        //查询当前目录下协作者的文件
        //查询当前用户作为协作者的文件id
        LambdaQueryWrapper<DocCollaborations> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(DocCollaborations::getCollaborationId, CurrentUserHolder.get().getCompanyUserId());
        List<DocFile> docFiles2 = null;
        List<DocCollaborations> docCollaborations = docCollaborationsMapper.selectList(queryWrapper2);

        if (CollectionUtil.isNotEmpty(docCollaborations)) {
            List<Long> fileIds = docCollaborations.stream().map(docCollaborations1 -> {
                return docCollaborations1.getFileId();
            }).collect(Collectors.toList());


            LambdaQueryWrapper<DocFile> queryWrapper3 = new LambdaQueryWrapper<>();
            queryWrapper3.eq(DocFile::getCompanyId,CurrentUserHolder.get().getCompanyId());
            queryWrapper3.eq(DocFile::getStatus,1);
            queryWrapper3.eq(DocFile::getFolderId, parentFolderId);
            queryWrapper3.eq(DocFile::getId, fileIds);
            docFiles2 = docFileMapper.selectList(queryWrapper3);
        }
        ArrayList<DocFile> docFileList = new ArrayList<>();
        docFileList.addAll(docFiles);
        docFileList.addAll(docFiles1);
        docFileList.addAll(docFiles2);
        //去重
        docFileList = CollectionUtil.distinct(docFileList);
        List<DocFileDto> docFileDtoList = BeanHelper.copyWithCollection(docFileList, DocFileDto.class);
        if (CollectionUtil.isNotEmpty(docFileDtoList)) {
            docFileDtoList.forEach(docFileDto -> {
                //创建者
                SysCompanyUserDTO userDTOCreate = userFeign.findUserById(docFileDto.getCreateUserId()).getData();
                docFileDto.setUserName(userDTOCreate.getUserName());
                //更新者
                SysCompanyUserDTO userDTOUpdate = userFeign.findUserById(docFileDto.getUpdateUserId()).getData();
                docFileDto.setUpdateUserName(userDTOUpdate.getUserName());
            });
        }

        return docFileDtoList;
    }

    /**
     * 查询文件夹列表
     *
     * @param parentFolderId
     * @return
     */
    private List<DocFolderDto> queryFoldersByParentFolderId(Long parentFolderId) {

        Long companyId = CurrentUserHolder.get().getCompanyId();
        LambdaQueryWrapper<DocFolder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocFolder::getCompanyId,companyId);
        wrapper.eq(DocFolder::getParentId,parentFolderId);
        List<DocFolder> docFolders = docFolderMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(docFolders)) {
            return BeanHelper.copyWithCollection(docFolders, DocFolderDto.class);
        }

        return null;
    }
}
